How to make a version-controlled markdown notebook

What is Markdown?

Markdown is a text-based language with a syntax that resembles the intuitive way we normally write. It can be rendered in a multitude of ways and easily converted into other formats, like PDF, Word Documents, and HTML web pages. It does not require anything more than a normal text editor, making it incredibly resistant to obsolescence, and because it uses git, it can be easily collaborative and edited from any device. They say the most effective notebooks are the ones that you use and stick with. This is a notebook I can see myself using 40 years from now, and one I could have used 20 years in the past. It may not be as fancy as squarespace, but I like the minimal feel and it reminds me of how the internet could have been more like a real library rather than a place for advertisements and monetizing attention.

How to create your notebook

  1. Download Typora, or any other markdown editor. I like Typora because it has a beautiful, yet minimal, user interface and renders the markdown in realtime, giving it the feel of any modern word processor, but with less clutter.
  2. Choose a folder for your notebook and create your first markdown file using typora. Note: You will need to learn the Syntax of Markdown.
  3. Install git, or Github Desktop, and create a git respository in your notebook folder. It isn't strictly necessary to version-control your notebook, but it provides a nice record and aids with backing the notebook up in case something happens to it.
  4. Save your file and create your first git commit.

How to turn your notebook into a HTML website

  1. Create a markdown file named index.md which will be the landing page for your eventual tree of HTML files. Make sure all your markdown notebook files are in a folder named ./markdown/.

  2. Make a folder in the root directory called ./www/ which will contain all the HTML files

  3. Using python, we can start to convert the markdown files to HTML files by creating a script. First import the necessary libraries and define locations for the directories.

   import markdown
   import os

   mdpath = "../markdown/"
   htmlpath = "../www/"
  1. Next, get the list of files using os:
   #  Get a list of filenames in your markdown notebook
   files = [f for f in os.listdir(mdpath) if f.endswith('.md')]
  1. Next, for each filename, open it, and convert it to HTML. Note the replace line, which helps convert markdown file references into hyperlinks.
   # For each markdown file, open it, convert it to HTML, and then create an HTML file in the /www/ folder
   for fn in files:  # for each file

       with open(mdpath+fn, 'r') as f:  # read file
           html = markdown.markdown(f.read())  # convert to markdown
           html = html.replace('.md"', '.html"')  # convert references to hyperlinks

       with open(htmlpath + (fn[0:-3])+".html", "w") as f:  # create blank HTML file
           f.write(html)  # write html to file

  1. Now, you can run this and it will create a directory of HTML files in /www/. Open index.html in your browser. What do you see? You may see the content of the markdown folder, but it's likely not formatted. Here it might benefit us to add some template code to the beginning and end of our HTML files.

(header.html)

   <!DOCTYPE html>
   <html lang="en">
   <head>
       <meta charset="UTF-8">
       <title>My first git-controlled markdown notebook</title>
       <style>
           body {background-color:#FEF9EC; max-width:800px; color:#163850;
             font-family: 'Courier New', monospace; font-size: 0.8em;}
           pre {font-size: 1.3em; color:#222;}
        h1 {font-weight:bold; font-size: 1.6em; margin-top:2em;}
           hr {margin-top: 4em; border: none; background-color: #555; color: #555; height: 1px;}
           a {color:#4799d9;}
           a:hover {color:#f6c243;}
           img {margin-top: 0em; max-width:100%;}
           input {font-family: inherit;}
       </style>
   </head>
   <body>

(footer.html)

   </body>
   </html>

(additions to the python script)

   # create a folder for our HTML templates and filenames for our HTML header and footer
   templatepath = "../templates/"
   header = "header.html"
   footer = "footer.html"

   #  Load the standard HTML headers and footers near the beginning of the script
   with open(templatepath+header, 'r') as f:
       header = f.read()
   with open(templatepath+footer, 'r') as f:
       footer = f.read()

   ...

   # Add f.write for header and footer when writing html files
   with open(htmlpath + (fn[0:-3])+".html", "w") as f:
           f.write(header)
           f.write(html)
           f.write(footer)


  1. At this point, run your script again and see if your HTML output looks different in the browser.

  2. If all is good at this point, try uploading the folder to a hosting service, like Amazon AWS Amplify and your markdown notebook is now available to others on the web!

  3. Here is the full script:

   import markdown
   import os

   mdpath = "../markdown/"
   htmlpath = "../www/"
   templatepath = "../templates/"
   header = "header.html"
   footer = "footer.html"

   #  Get a list of filenames in your markdown notebook
   files = [f for f in os.listdir(mdpath) if f.endswith('.md')]

   #  Load the standard HTML headers and footers
   with open(templatepath+header, 'r') as f:
       header = f.read()
   with open(templatepath+footer, 'r') as f:
       footer = f.read()


   # For each markdown file, open it, convert it to HTML, and then create an HTML file in the /www/ folder
   for fn in files:

       with open(mdpath+fn, 'r') as f:
           html = markdown.markdown(f.read())
           html = html.replace('.md"', '.html"')

       with open(htmlpath + (fn[0:-3])+".html", "w") as f:
           f.write(header)
           f.write(html)
           f.write(footer)

Enjoy!